﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using UtilZ.Dotnet.Ex.Base;
using UtilZ.Dotnet.Ex.Communication.Base;
using UtilZ.Dotnet.Ex.Communication.Net.Base;
using UtilZ.Dotnet.Ex.Communication.Net.Udp;
using UtilZ.Dotnet.Ex.Log;

namespace DotnetWinFormApp
{
    public partial class FBroadcast : Form
    {
        public FBroadcast()
        {
            InitializeComponent();
        }

        private void FBroadcast_Load(object sender, EventArgs e)
        {
            var redirectAppenderToUI = (RedirectAppender)Loger.GetAppenderByName(null, "RedirectToUI");
            if (redirectAppenderToUI != null)
            {
                redirectAppenderToUI.RedirectOuput += RedirectLogOutput;
            }
        }

        private void RedirectLogOutput(object sender, RedirectOuputArgs e)
        {
            logControl1.AddLog(e.Item.Content, e.Item.Level);

            //string str;
            //try
            //{
            //    str = string.Format("{0} {1}", DateTime.Now, e.Item.Content);
            //}
            //catch (Exception ex)
            //{
            //    str = ex.Message;
            //}

            //logControl.AddLog(str, e.Item.Level);
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            logControl1.Clear();
        }






        private NetUdpClient _broadcastUdpClient = null;
        private NetUDPUnpacker _unpacker;


        private void btnListenBroadcast_Click(object sender, EventArgs e)
        {
            try
            {
                var broadcastPort = (int)numBroadcast.Value;
                this._unpacker = new NetUDPUnpacker();
                this._unpacker.PackOutput += _unpacker_PackOutput;

                var initPara = new NetUdpClientInitPara(this._unpacker, new IPEndPoint(IPAddress.Any, broadcastPort))
                {
                    Transfer = UDPTransferMode.Broadcast
                };
                this._broadcastUdpClient = new NetUdpClient(initPara);
                this._broadcastUdpClient.Start();

                Loger.Info("已开启广播监听");
            }
            catch (Exception ex)
            {
                Loger.Error(ex, "开启监听广播异常");
            }
        }

        private void _unpacker_PackOutput(object sender, DataOutputArgs e)
        {
            var netLinkInfo = (NetLinkInfo)e.LinkInfo;
            string localEPStr = NetHelper.GetIPPortString(netLinkInfo.LocalEndPoint);
            string remoteEPStr = NetHelper.GetIPPortString(netLinkInfo.RemoteEndPoint);
            string json = Encoding.UTF8.GetString(e.Data.Bytes, e.Data.Offset, e.Data.Length);
            Loger.Info($"收到广播消息:{remoteEPStr}->{localEPStr}:\r\n{json}");
        }


        private void btnBroadcast_Click(object sender, EventArgs e)
        {
            try
            {
                if (this._broadcastUdpClient == null)
                {
                    Loger.Warn("先开启广播监听");
                    return;
                }

                string json = $"{TimeEx.GetTimestamp()}请求建立连接";
                byte[] buffer = Encoding.UTF8.GetBytes(json);
                var broadcastPort = (int)numBroadcast.Value;

                if (string.IsNullOrWhiteSpace(txtBroadcastAddr.Text))
                {
                    //IPAddress[] ipAddrArr = NetHelper.GetAllIPV4(AddressFamily.InterNetwork);
                    //string ipStr, ipStr2;
                    //int index;

                    //foreach (var ipAddr in ipAddrArr)
                    //{
                    //    ipStr = ipAddr.ToString();
                    //    index = ipStr.LastIndexOf('.');
                    //    ipStr2 = ipStr.Substring(0, index) + ".255";
                    //    var broadcastEndpoint = new IPEndPoint(IPAddress.Parse(ipStr2), broadcastPort);
                    //    this._broadcastUdpClient.Send(buffer, broadcastEndpoint);
                    //    Loger.Info($"{NetHelper.GetIPPortString(broadcastEndpoint)}发送广播成功");
                    //}

                    var broadcastEndpoint = new IPEndPoint(IPAddress.Broadcast, broadcastPort);
                    this._broadcastUdpClient.SendTo(buffer, broadcastEndpoint);
                    Loger.Info($"{NetHelper.GetIPPortString(broadcastEndpoint)}发送广播成功");
                }
                else
                {
                    var broadcastEndpoint = new IPEndPoint(IPAddress.Parse(txtBroadcastAddr.Text), broadcastPort);
                    this._broadcastUdpClient.SendTo(buffer, broadcastEndpoint);
                    Loger.Info($"{NetHelper.GetIPPortString(broadcastEndpoint)}发送广播成功");
                }

            }
            catch (Exception ex)
            {
                Loger.Error(ex, "发送广播异常");
            }
        }


    }


    internal class BroadcastUnpacker : UnpackerAbs
    {

        public BroadcastUnpacker()
        {

        }

        protected override int PrimitiveUnPackge(IUnpackerPara unpackerPara)
        {
            throw new NotImplementedException();
        }
    }
}
